from django.core.serializers.json import json
from django.http import JsonResponse, HttpResponse
from rest_framework.response import Response
from rest_framework import permissions, status
from rest_framework.settings import api_settings
from rest_framework_mongoengine import viewsets

from authorshow.models.models import StandardResultSetPagination
from authorshow.models.utils import create_coll_id
from foundation.models import FundChina, FundEU, FundUSA
from foundation.serializer import FundChinaSerializer, ListFundChinaSerializer, FundEUSerializer, ListFundEUSerializer, \
    FundUSASerializer, ListFundUSASerializer
from mongoengine import QuerySet

from foundation.utils import select_fund, select_EU, select_USA


def perform_create(self, serializer):
    serializer.save()


def perform_update(self, serializer):
    serializer.save()


def get_success_headers(self, data):
    try:
        return {'Location': str(data[api_settings.URL_FIELD_NAME])}
    except (TypeError, KeyError):
        return {}

class FundChinaViewSet(viewsets.ModelViewSet):
    serializer_class = FundChinaSerializer
    queryset: QuerySet = FundChina.objects.all()

    # 用于分页
    pagination_class = StandardResultSetPagination
    # 权限控制
    permission_classes = (
        permissions.IsAuthenticatedOrReadOnly,
    )

    def create(self, request, *args, **kwargs):
        """
        创建一个新的instance,自动生成唯一的id值.
        """
        data = request.data
        data['id'] = str(create_coll_id(queryset=self.get_queryset()))
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(data=serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def list(self, request, *args, **kwargs):
        """
        由搜索结果展示fundchina内容
        """
        params = request.query_params
        org = params.get(key='org')
        info = params.get(key='info')

        if not (org or info):
            queryset = self.filter_queryset(self.get_queryset())
            page = self.paginate_queryset(queryset=queryset)
            serializer = ListFundChinaSerializer(instance=page, many=True)
            return self.get_paginated_response(serializer.data)
        r_result = select_fund(queryset=self.queryset, info=info, org=org)
        if r_result is None or r_result.count() is 0:
            err_msg = "未查询到结果"
            return Response(data=err_msg, status=status.HTTP_404_NOT_FOUND)
        page = self.paginate_queryset(queryset=r_result)
        # 序列化所有字段
        serializer = ListFundChinaSerializer(instance=page, many=True)
        return self.get_paginated_response(serializer.data)

class FundEUViewSet(viewsets.ModelViewSet):
    serializer_class = FundEUSerializer
    queryset: QuerySet = FundEU.objects.all()

    pagination_class = StandardResultSetPagination
    # 权限控制
    permission_classes = (
        permissions.IsAuthenticatedOrReadOnly,
    )

    def create(self, request, *args, **kwargs):
        """
        创建一个新的instance,自动生成唯一的id值.
        """
        data = request.data
        data['id'] = str(create_coll_id(queryset=self.get_queryset()))
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(data=serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def list(self, request, *args, **kwargs):
        params = request.query_params
        info = params.get(key='info')
        coordinator = params.get(key='coordinator')
        if not (info or coordinator):
            queryset = self.filter_queryset(self.get_queryset())
            page = self.paginate_queryset(queryset=queryset)
            serializer = ListFundEUSerializer(instance=page, many=True)
            return self.get_paginated_response(serializer.data)
        r_result = select_EU(queryset=self.queryset, info=info, coordinator=coordinator)
        if r_result is None or r_result.count() is 0:
            err_msg = "未查询到结果"
            return Response(data=err_msg, status=status.HTTP_404_NOT_FOUND)
        page = self.paginate_queryset(queryset=r_result)
        # 序列化所有字段
        serializer = ListFundEUSerializer(instance=page, many=True)
        return self.get_paginated_response(serializer.data)

class FundUSAViewSet(viewsets.ModelViewSet):
    serializer_class = FundUSASerializer
    queryset: QuerySet = FundUSA.objects.all()

    pagination_class = StandardResultSetPagination
    # 权限控制
    permission_classes = (
        permissions.IsAuthenticatedOrReadOnly,
    )

    def create(self, request, *args, **kwargs):
        """
        创建一个新的instance,自动生成唯一的id值.
        """
        data = request.data
        data['id'] = str(create_coll_id(queryset=self.get_queryset()))
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(data=serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def list(self, request, *args, **kwargs):
        params = request.query_params
        info = params.get(key='info')
        unit = params.get(key='unit')

        if not (unit or info):
            queryset = self.filter_queryset(self.get_queryset())
            page = self.paginate_queryset(queryset=queryset)
            serializer = ListFundUSASerializer(instance=page, many=True)
            return self.get_paginated_response(serializer.data)
        r_result = select_USA(queryset=self.queryset, unit=unit, info=info)
        if r_result is None or r_result.count() is 0:
            err_msg = "未查询到结果"
            return Response(data=err_msg, status=status.HTTP_404_NOT_FOUND)
        page = self.paginate_queryset(queryset=r_result)
        # 序列化所有字段
        serializer = ListFundUSASerializer(instance=page, many=True)
        return self.get_paginated_response(serializer.data)

def fund_count(request):
    '''对各个基金库项目数量进行统计'''
    count = {}
    count['中国科学基金'] = FundChina.objects.all().count()
    count['欧盟框架计划'] = FundEU.objects.all().count()
    count['美国科学基金'] = FundUSA.objects.all().count()
    # return JsonResponse(count, json_dumps_params={'ensure_ascii': False})
    res = json.dumps(count, indent=4, ensure_ascii=False)
    return HttpResponse(res, content_type='application/json', charset='utf-8')
    # 内置设置如下(在Python安装文件lib/site-packages中创建新文件sitecustomize.py声明整体编码)
    # res = json.dumps(count, indent=4, ensure_ascii=False)
    # return HttpResponse(res, content_type='application/json', charset='gbk')

def pics_count(request):
    '''由搜索框对中国科学基金项目负责人统计'''
    all_pics_count = {}
    all_pics = []
    pics_count = {}
    pics = []
    info = request.GET.get('info', None)
    org = request.GET.get('org', None)
    queryset = FundChina.objects()
    if not (info or org):
        for document in queryset:
            all_pics.append(document.pic)
        for i in all_pics:
            if i in all_pics_count:
                all_pics_count[i] += 1
            else:
                all_pics_count[i] = 1
        k = {}
        sort_rank = sorted(all_pics_count.items(), key=lambda x: x[1], reverse=True)  # 进行降序排列
        for i in sort_rank:
            k[i[0]] = all_pics_count[i[0]]
        # return JsonResponse(k, json_dumps_params={"ensure_ascii": False})
        res = json.dumps(k, indent=4, ensure_ascii=False)
        return HttpResponse(res, content_type='application/json', charset='utf-8')
    # 获取筛选数据
    result = select_fund(queryset=queryset, info=info, org=org)
    if result is None or result.count() is 0:
        err_msg = "未查询到结果"
        # return Response(data=err_msg, status=status.HTTP_404_NOT_FOUND)
        return HttpResponse(err_msg)
    for document in result:
        pics.append(document.pic)
    for i in pics:
        if i in pics_count:
            pics_count[i] += 1
        else:
            pics_count[i] = 1
    l = {}
    sort_rank = sorted(pics_count.items(), key=lambda x: x[1], reverse=True)  # 进行降序排列
    for i in sort_rank:
        l[i[0]] = pics_count[i[0]]
    # return JsonResponse(l, json_dumps_params={'ensure_ascii': False})
    res = json.dumps(l, indent=4, ensure_ascii=False)
    return HttpResponse(res, content_type='application/json', charset='utf-8')


# def pics_count(request):
#     '''中国科学基金项目负责人/pic统计'''
#     pics_dict = {}
#     pics = []
#
#     for document in FundChina.objects():
#         pics.append(document.pic)
#
#     for i in pics:
#         if i in pics_dict:
#             pics_dict[i] += 1
#         else:
#             pics_dict[i] = 1
#
#     k = {}
#     sort_rank = sorted(pics_dict.items(), key=lambda x: x[1], reverse=True)
#     for i in sort_rank:  # 将排序前10的关键词写入新的字典中
#         k[i[0]] = pics_dict[i[0]]
#     return JsonResponse(k, json_dumps_params={'ensure_ascii': False}, safe=False)

    # '''注意到不同机构的pic可能相同,此时应该分别计数'''
    # pics_dict = {}
    # orgs = []
    # kkk = []

    # for document in FundChina.objects():
    #     orgs.append(document.org)
    # kkk = list(set(orgs))

    # for name in kkk:
    #     pics_dict[name] = []
    #     for document in FundChina.objects():
    #         if document.org == name:
    #             pics_dict[name].append(document.pic)
    # result = {}
    # for key in pics_dict:
    #     result[key] = {}
    #     for i in pics_dict[key]:
    #         if i in result[key]:
    #             result[key][i] += 1
    #         else:
    #             result[key][i] = 1

    # pics = []
    # for key, value in result.items():
    #     pics.append(value)
    #     '''字典的键一般是唯一的,但是后面的值会覆盖前面的值'''
        # for i in range(len(value)):
        #     for k, v in value.items():
        #         pics[k] = v

    # return JsonResponse(pics_dict, json_dumps_params={'ensure_ascii': False}, safe=False)

def orgs_count(request):
    '''由搜索框搜索中国科学基金项目机构统计'''
    all_orgs_dict = {}
    all_orgs = []
    orgs_dict = {}
    orgs = []
    info = request.GET.get('info', None)
    org = request.GET.get('org', None)
    queryset = FundChina.objects()
    if not (info or org):
        '''若搜索框中没有参数,显示所有的机构统计图'''
        for document in queryset:
            all_orgs.append(document.org)
        for i in all_orgs:
            if i in all_orgs_dict:
                all_orgs_dict[i] += 1
            else:
                all_orgs_dict[i] =1
        # 降序排列
        k = {}
        sort_rank = sorted(all_orgs_dict.items(), key=lambda x: x[1], reverse=True)  # 进行降序排列
        for i in sort_rank:  # 将排序前10的关键词写入新的字典中
            k[i[0]] = all_orgs_dict[i[0]]
        # return JsonResponse(k, json_dumps_params={'ensure_ascii': False})
        res = json.dumps(k, indent=4, ensure_ascii=False)
        return HttpResponse(res, content_type='application/json', charset='utf-8')
    # 获取搜索框数据
    result = select_fund(queryset=queryset, info=info, org=org)
    if result is None or result.count() is 0:
        err_msg = "未查询到结果"
        # return Response(data=err_msg, status=status.HTTP_404_NOT_FOUND)
        return HttpResponse(err_msg)
    for document in result:
        orgs.append(document.org)
        for i in orgs:
            if i in orgs_dict:
                orgs_dict[i] += 1
            else:
                orgs_dict[i] = 1
    l = {}
    sort_rank = sorted(orgs_dict.items(), key=lambda x: x[1], reverse=True)  # 进行降序排列
    for i in sort_rank:
        l[i[0]] = orgs_dict[i[0]]
    # return JsonResponse(l, json_dumps_params={'ensure_ascii': False})
    res = json.dumps(l, indent=4, ensure_ascii=False)
    return HttpResponse(res, content_type='application/json', charset='utf-8')
# def orgs_count(request):
#     '''中国科学基金项目机构/org统计'''
#     orgs_dict = {}
#     orgs = []
#
#     for document in FundChina.objects():
#         orgs.append(document.org)
#
#     for i in orgs:
#         if i in orgs_dict:
#             orgs_dict[i] += 1
#         else:
#             orgs_dict[i] = 1
#     k = {}
#     sort_rank = sorted(orgs_dict.items(), key=lambda x: x[1], reverse=True)    # 进行降序排列
#     for i in sort_rank:  # 将排序前10的关键词写入新的字典中
#         k[i[0]] = orgs_dict[i[0]]
#     return JsonResponse(k, json_dumps_params={'ensure_ascii': False})

def secondClass_count(request):
    '''由搜索框搜索中国科学基金二级学科统计'''
    all_secondClass_dict = {}
    all_secondClass = []
    secondClass_dict = {}
    secondClass = []
    info = request.GET.get('info', None)
    org = request.GET.get('org', None)
    queryset = FundChina.objects()
    if not (info or org):
        for document in queryset:
            all_secondClass.append(document.subjectClass.second_level)
        for i in all_secondClass:
            if i in all_secondClass_dict:
                all_secondClass_dict[i] += 1
            else:
                all_secondClass_dict[i] = 1
        # 添加降序排列
        l = {}
        sort_rank = sorted(all_secondClass_dict.items(), key=lambda x: x[1], reverse=True)  # 进行降序排列
        for i in sort_rank:
            l[i[0]] = all_secondClass_dict[i[0]]
        # return JsonResponse(l, json_dumps_params={"ensure_ascii": False})
        res = json.dumps(l, indent=4, ensure_ascii=False)
        return HttpResponse(res, content_type='application/json', charset='utf-8')
    # 获取筛选数据
    result = select_fund(queryset=queryset, info=info, org=org)
    if result is None or result.count() is 0:
        err_msg = "未查询到结果"
        # return Response(data=err_msg, status=status.HTTP_404_NOT_FOUND)
        return HttpResponse(err_msg)
    for document in result:
        secondClass.append(document.subjectClass.second_level)
    for i in secondClass:
        if i in secondClass_dict:
            secondClass_dict[i] += 1
        else:
            secondClass_dict[i] = 1
    # 降序排列
    k = {}
    sort_rank = sorted(secondClass_dict.items(), key=lambda x: x[1], reverse=True)  # 进行降序排列
    for i in sort_rank:
        k[i[0]] = secondClass_dict[i[0]]
    # return JsonResponse(k, json_dumps_params={'ensure_ascii': False})
    res = json.dumps(k, indent=4, ensure_ascii=False)
    return HttpResponse(res, content_type='application/json', charset='utf-8')


def thirdClass_count(request):
    '''由搜索框搜索中国科学基金二级学科统计'''
    all_thirdClass_dict = {}
    all_thirdClass = []
    thirdClass_dict = {}
    thirdClass = []
    info = request.GET.get('info', None)
    org = request.GET.get('org', None)
    queryset = FundChina.objects()
    if not (info or org):
        for document in queryset:
            all_thirdClass.append(document.subjectClass.third_level)
        for i in all_thirdClass:
            if i in all_thirdClass_dict:
                all_thirdClass_dict[i] += 1
            else:
                all_thirdClass_dict[i] = 1
        l = {}
        sort_rank = sorted(all_thirdClass_dict.items(), key=lambda x: x[1], reverse=True)  # 进行降序排列
        for i in sort_rank:
            l[i[0]] = all_thirdClass_dict[i[0]]
        # return JsonResponse(l, json_dumps_params={"ensure_ascii": False})
        res = json.dumps(l, indent=4, ensure_ascii=False)
        return HttpResponse(res, content_type='application/json', charset='utf-8')
    # 获取筛选数据
    result = select_fund(queryset=queryset, info=info, org=org)
    if result is None or result.count() is 0:
        err_msg = "未查询到结果"
        # return Response(data=err_msg, status=status.HTTP_404_NOT_FOUND)
        return HttpResponse(err_msg)
    for document in result:
        thirdClass.append(document.subjectClass.third_level)
    for i in thirdClass:
        if i in thirdClass_dict:
            thirdClass_dict[i] += 1
        else:
            thirdClass_dict[i] = 1
    k = {}
    sort_rank = sorted(thirdClass_dict.items(), key=lambda x: x[1], reverse=True)  # 进行降序排列
    for i in sort_rank:
        k[i[0]] = thirdClass_dict[i[0]]
    # return JsonResponse(k, json_dumps_params={'ensure_ascii': False})
    res = json.dumps(k, indent=4, ensure_ascii=False)
    return HttpResponse(res, content_type='application/json', charset='utf-8')

# def secondClass_count(request):
#     '''中国科学基金二级学科统计'''
#     secondClass_dict = {}
#     secondClass = []
#
#     for document in FundChina.objects():
#         secondClass.append(document.subjectClass.second_level)
#
#     for i in secondClass:
#         if i in secondClass_dict:
#             secondClass_dict[i] += 1
#         else:
#             secondClass_dict[i] = 1
#     return JsonResponse(secondClass_dict, json_dumps_params={'ensure_ascii': False})

# def thirdClass_count(request):
#     '''中国科学基金三级学科统计'''
#     thirdClass_dict = {}
#     thirdClass = []
#
#     for document in FundChina.objects():
#         thirdClass.append(document.subjectClass.third_level)
#
#     for i in thirdClass:
#         if i in thirdClass_dict:
#             thirdClass_dict[i] += 1
#         else:
#             thirdClass_dict[i] = 1
#     return JsonResponse(thirdClass_dict, json_dumps_params={'ensure_ascii': False})
